package com.btcode.common;

import com.btcode.exception.MsgException;
import java.util.HashMap;
import java.util.Map;

/**
 * 单例抽象类
 *
 * @author gislin
 */
public abstract class AbstractSingleton {

    private static Map<String, AbstractSingleton> registryMap = new HashMap<String, AbstractSingleton>();

    protected AbstractSingleton() {
        String clazzName = this.getClass().getName();
        if (registryMap.containsKey(clazzName)) {
            throw new MsgException("Cannot construct instance for class " + clazzName
                                       + ", since an instance already exists!");
        }
        else {
            synchronized (registryMap) {
                if (registryMap.containsKey(clazzName)) {
                    throw new MsgException("Cannot construct instance for class " + clazzName
                                               + ", since an instance already exists!");
                }
                else {
                    registryMap.put(clazzName, this);
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    public static <T extends AbstractSingleton> T getInstance(final Class<T> clazz) {
        String clazzName = clazz.getName();
        try {
            if (!registryMap.containsKey(clazzName)) {
                synchronized (registryMap) {
                    if (!registryMap.containsKey(clazzName)) {
                        T instance = clazz.newInstance();
                        return instance;
                    }
                }
            }
        }
        catch (Exception e) {
            throw new MsgException("初始化" + clazz + "出错", e);
        }

        return (T) registryMap.get(clazzName);
    }

}
